import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import javax.smartcardio.CardException;
import javax.smartcardio.CardNotPresentException;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.border.TitledBorder;
/**
 * 发送指令
 * 
 * @author LinCH
 *
 */
public class pcsc extends JFrame implements ActionListener,
		PollingEvent.CardPollingHandler {
	// JPCSC Variables
	int retCode;
	boolean connActive;

	int[] ATRLen = new int[1];
	int[] hContext = new int[1];
	int[] cchReaders = new int[1];
	int[] hCard = new int[1];
	int[] PrefProtocols = new int[1];
	int[] RecvLen = new int[1];
	int[] plpreturn = new int[1];
	int SendLen = 0;
	byte[] SendBuff = new byte[300];
	byte[] RecvBuff = new byte[300];
	byte[] ATRVal = new byte[128];
	byte[] szReaders = new byte[1024];

	// GUI Variables
	private JButton bConnect, bInit, bQuit, bSet, bReset, bWrite, bclear;
	private JComboBox cbReader;
	private JPanel functionsPanel;
	private JLabel lblCardMessage, lblCardNote, lblSet, lblRec, lblReader,
			lblSetMode, lblSetMessage;
	private JTextField tCardMessage, tSet;
	private JRadioButton radioButton, radioButton1, radioButton2;
	private ButtonGroup group;
	private JTextArea SetMessage, GetMessage;
	private int Mode = 2;
	private int ModeValue = 3500;

	private PcscReader _pcscReader;
	private CardSelector acr;

	public pcsc() {
		init();
		initMenu();
	}

	/**
	 * 初始化界面
	 * */
	private void init() {
		setTitle("PCSC  direct");
		setSize(400, 430);
		this.setResizable(false);
		this.setTitle("PCSC程序");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocation();
		lblReader = new JLabel();
		cbReader = new JComboBox();
		bInit = new JButton();
		lblCardNote = new JLabel();
		bConnect = new JButton();
		functionsPanel = new JPanel();
		lblSetMode = new JLabel("直接模式命令：");
		lblCardMessage = new JLabel();
		lblRec = new JLabel();
		tSet = new JTextField(5);
		lblSet = new JLabel();
		tCardMessage = new JTextField(23);
		bSet = new JButton();
		bWrite = new JButton();
		bReset = new JButton();
		bQuit = new JButton();
		bclear = new JButton();
		radioButton = new JRadioButton();
		radioButton1 = new JRadioButton("共享模式（APDU）", true);
		radioButton2 = new JRadioButton();
		group = new ButtonGroup();
		lblSetMessage = new JLabel();
		SetMessage = new JTextArea(3, 24);
		GetMessage = new JTextArea(5, 24);
		GetMessage.setLineWrap(true);
		GetMessage.setPreferredSize(new Dimension(5, 40));

		lblReader.setText("Select Reader");

		String[] rdrNameDef = { "Please select reader " };
		cbReader = new JComboBox(rdrNameDef);
		cbReader.setSelectedIndex(0);
		bInit.setText("刷新");
		bConnect.setText("连接");
		lblCardMessage.setText("卡片复位信息：");
		lblSet.setText("直接发送命令:");
		bSet.setText("发送");
		bclear.setText("清除数据");
		bQuit.setText("退出");
		bReset.setText("重置");
		lblSetMessage.setText("发送数据：");
		lblRec.setText("回复信息：");
		tSet.setText("3500");
		SetMessage.setText("00 84 00 00 08");
		GetMessage.setText("");
		radioButton.setText("直接模式（无卡操作）");
		radioButton2.setText("独有模式");
		lblCardNote.setText("注意事项：使用直接模式前需激活Command  ACR1281:3500");
		functionsPanel.setBorder(BorderFactory
				.createTitledBorder("连接模式-默认为共享模式"));
		setContentPane(createContentPane());
	}

	/**
	 * 主界面面板
	 * */
	private JPanel createContentPane() {
		JPanel jPanel = new JPanel(new BorderLayout());
		jPanel.setBounds(10, 5, 10, 5);
		jPanel.add(BorderLayout.NORTH, CreatNPane());
		jPanel.add(BorderLayout.CENTER, CreatCPane());
		return jPanel;
	}

	/**
	 * 界面中間
	 * */
	private JPanel CreatCPane() {
		JPanel jPanel = new JPanel(new BorderLayout());
		jPanel.add(BorderLayout.NORTH, CreatPane4());
		jPanel.add(BorderLayout.CENTER, CreatPane3());
		return jPanel;
	}

	private JPanel CreatPane2() {
		JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 5));
		jPanel.add(lblCardMessage);
		jPanel.add(tCardMessage);
		return jPanel;
	}

	private JPanel CreatPane6() {
		JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 5));
		jPanel.add(lblSetMode);
		jPanel.add(tSet);
		jPanel.add(bSet);
		jPanel.add(new JLabel("ACR1222:2079"));
		bSet.addActionListener(this);
		return jPanel;
	}

	private JPanel CreatPane3() {
		JPanel jPanel = new JPanel(new BorderLayout());
		jPanel.add(BorderLayout.NORTH, CreatPane2());
		jPanel.add(BorderLayout.CENTER, CreatPane5());
		return jPanel;
	}

	private Component CreatPane7() {
		JPanel jPanel = new JPanel(new BorderLayout());
		jPanel.add(BorderLayout.NORTH, CreatPane8());
		jPanel.add(BorderLayout.CENTER, CreatPane9());
		jPanel.add(BorderLayout.SOUTH, CreatPane10());
		return jPanel;
	}

	private Component CreatPane10() {
		JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 1));
		jPanel.add(bReset);
		jPanel.add(bclear);
		jPanel.add(bQuit);
		bReset.addActionListener(this);
		bclear.addActionListener(this);
		bQuit.addActionListener(this);
		return jPanel;
	}

	private Component CreatPane8() {
		JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 1));
		jPanel.add(lblSetMessage);
		jPanel.add(SetMessage);
		return jPanel;
	}

	private Component CreatPane9() {
		JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 1));
		jPanel.add(lblRec);
		jPanel.add(GetMessage);
		return jPanel;
	}

	private Component CreatPane5() {
		JPanel jPanel = new JPanel(new BorderLayout());
		jPanel.add(BorderLayout.NORTH, new JLabel(
				"注意事项： 使用直接模式前需Escape Command ACR1281:3500 "));
		jPanel.add(BorderLayout.CENTER, CreatPane6());
		jPanel.add(BorderLayout.SOUTH, CreatPane7());
		return jPanel;
	}

	private JPanel CreatPane4() {
		JPanel jPanel = new JPanel(new BorderLayout());
		jPanel.setBorder(new TitledBorder("连接模式-默认为共享模式"));
		group.add(radioButton);
		group.add(radioButton1);
		group.add(radioButton2);
		jPanel.add(BorderLayout.WEST, radioButton);
		jPanel.add(BorderLayout.CENTER, radioButton1);
		jPanel.add(BorderLayout.EAST, radioButton2);
		radioButton.addActionListener(this);
		radioButton1.addActionListener(this);
		radioButton2.addActionListener(this);
		return jPanel;
	}

	/**
	 * 界面上部分
	 * */
	private JPanel CreatNPane() {
		JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 5));
		jPanel.setBounds(10, 20, 20, 50);
		String[] rdrNameDef = { "Please select reader                   " };
		cbReader = new JComboBox(rdrNameDef);
		cbReader.setSelectedIndex(0);
		cbReader.setPreferredSize(new Dimension(200, 30));
		jPanel.add(cbReader);
		jPanel.add(bInit);
		jPanel.add(bConnect);
		bInit.addActionListener(this);
		bConnect.addActionListener(this);
		return jPanel;
	}

	public void setLocation() {
		Toolkit toolKit = Toolkit.getDefaultToolkit();
		Dimension screen = toolKit.getScreenSize();
		int x = (screen.width - getWidth()) / 2;
		int y = (screen.height - getHeight()) / 2;
		setLocation(x, y);
	}

	public void clearBuffers() {

		for (int i = 0; i < 300; i++) {

			SendBuff[i] = 0x00;
			RecvBuff[i] = 0x00;

		}

	}

	public void initMenu() {

		connActive = false;
		bInit.setEnabled(true);
		bConnect.setEnabled(false);
		bWrite.setEnabled(false);
		bWrite.setEnabled(false);

		bConnect.setEnabled(false);
		radioButton.setEnabled(false);
		radioButton1.setEnabled(false);
		radioButton2.setEnabled(false);
		tCardMessage.setEnabled(false);
		tSet.setEnabled(false);
		bSet.setEnabled(false);
		SetMessage.setEnabled(false);
		GetMessage.setEditable(false);
	}

	public enum CARD_STATUS {
		CARD_FOUND(0), CARD_REMOVED(1), ERROR(2);

		private final int _id;

		CARD_STATUS(int id) {
			this._id = id;
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		pcsc pcsc1 = new pcsc();
		pcsc1.setVisible(true);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (bInit == e.getSource()) {
			String[] readerList = null;

			try {
				_pcscReader = new PcscReader();

				// Instantiate an event handler object
				_pcscReader.setPollingEventHandler(new PollingEvent());

				// Register the event handler implementation of this class
				_pcscReader.getPollingEventHandler().addEventListener(this);

				acr = new CardSelector(_pcscReader);
				_pcscReader.setEventHandler(new ReaderEvents());

				readerList = _pcscReader.listTerminals();
			} catch (Exception ex) {
				ex.printStackTrace();
				return;
			} finally {
				if (readerList == null) {
					JOptionPane.showMessageDialog(this,
							"No PC/SC reader detected");
					return;
				} else {
					cbReader.removeAllItems();

					for (int i = 0; i < readerList.length; i++) {
						if (!readerList.equals(""))
							cbReader.addItem(readerList[i]);
						else
							break;
					}

					cbReader.setSelectedIndex(0);
					bConnect.setEnabled(true);
					bInit.setEnabled(false);
					radioButton.setEnabled(true);
					radioButton1.setEnabled(true);
					radioButton2.setEnabled(true);
					bSet.setEnabled(false);
				}
			}
		}

		if (bConnect == e.getSource()) {

			if (bConnect.getText().equals("连接")) {
				String rdrcon = (String) cbReader.getSelectedItem();
				if (Mode == 1) {
					try {
						if (_pcscReader._connectionActive)
							_pcscReader.disconnect();

						_pcscReader.connectDirect(rdrcon);
					} catch (Exception e2) {
						// TODO: handle exception
					}

					connActive = true;
					radioButton.setEnabled(false);
					radioButton1.setEnabled(false);
					radioButton2.setEnabled(false);
					bConnect.setText("断开");
					bSet.setEnabled(true);
					SetMessage.setEnabled(true);
					tCardMessage.setText("没有卡片复位信息(复位信息长度 = 0) ");
					tCardMessage.setEnabled(false);
					SetMessage.setText("E0 00 00 18 00");
				} else if (Mode == 2) {
					SetMessage.setText("00 84 00 00 08");
					String atr = "";
					try {
						if (_pcscReader._connectionActive)
							_pcscReader.disconnect();
						_pcscReader.connect(rdrcon, "*");
					} catch (Exception ex) {
						GetMessage.setText(ex.getMessage().toString());
						return;
					}
					try {
						atr = acr.getAtr();
						if (atr.equals("")) {
							return;
						}
						tCardMessage.setText(atr);
						tCardMessage.setEnabled(true);
					} catch (Exception e2) {
						GetMessage.setText(e2.getMessage().toString());
					}
					connActive = true;
					radioButton.setEnabled(false);
					radioButton1.setEnabled(false);
					radioButton2.setEnabled(false);
					bConnect.setText("断开");
					bSet.setEnabled(true);
					SetMessage.setEnabled(true);
				} else {
					connActive = true;
					radioButton.setEnabled(false);
					radioButton1.setEnabled(false);
					radioButton2.setEnabled(false);
					bConnect.setText("断开");
					bSet.setEnabled(true);
					SetMessage.setEnabled(true);
				}

			} else {
				bInit.setEnabled(true);
				connActive = true;
				radioButton.setEnabled(true);
				radioButton1.setEnabled(true);
				radioButton2.setEnabled(true);
				bConnect.setText("连接");
				bSet.setEnabled(false);
				tCardMessage.setText("");
				tCardMessage.setEditable(false);
				SetMessage.setEnabled(false);
			}
		}

		if (bSet == e.getSource()) {
			if (Mode == 2) {
				String string = SetMessage.getText().trim().replaceAll(" ", "");
				System.out.println(string.length());
				if (string.equals("")) {
					SetMessage.requestFocus();
					return;
				} else if (string.length() < 10) {
					SetMessage.setText("00 84 00 00 08");
					SetMessage.requestFocus();
					return;
				}
				if (string.length() % 2 != 0) {
					string = string + "0";
				}
				System.out.println(string);
				byte[] buff = new byte[string.length() / 2];
				int b = 0;
				for (int i = 0; i < string.length(); i = i + 2) {
					buff[b] = (byte) ((Integer) Integer.parseInt(
							string.substring(i, i + 2), 16)).byteValue();
					b++;
				}
				try {
					GetMessage.setText(acr.apdu(buff));
				} catch (Exception e1) {
					GetMessage.setText("63 00");
				}
			} else if (Mode == 1) {
				// 直接模式指令发送
				String string = SetMessage.getText().trim().replaceAll(" ", "");
				System.out.println(string.length());
				if (string.equals("")) {
					SetMessage.requestFocus();
					return;
				} else if (string.length() < 10) {
					SetMessage.setText("E0 00 18 00 00");
					SetMessage.requestFocus();
					return;
				}
				if (string.length() % 2 != 0) {
					string = string + "0";
				}
				System.out.println(string);
				byte[] buff = new byte[string.length() / 2];
				int b = 0;
				for (int i = 0; i < string.length(); i = i + 2) {
					buff[b] = (byte) ((Integer) Integer.parseInt(
							string.substring(i, i + 2), 16)).byteValue();
					b++;
				}
				try {
					GetMessage.setText(acr.Controlapdu(buff, 3500));
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

		}

		if (bQuit == e.getSource()) {
			this.dispose();
			System.exit(0);
		}

		if (bclear == e.getSource()) {
			SetMessage.setText("");
			GetMessage.setText("");
		}

		if (bReset == e.getSource()) {
			if (_pcscReader.isConnectionActive())
				try {
					_pcscReader.disconnect();
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			cbReader.removeAllItems();
			cbReader.addItem("Please select reader                   ");
			bConnect.setText("连接");
			connActive = false;
			bInit.setEnabled(true);
			bConnect.setEnabled(false);
			bWrite.setEnabled(false);
			bWrite.setEnabled(false);

			bConnect.setEnabled(false);
			radioButton.setEnabled(false);
			radioButton1.setEnabled(false);
			radioButton2.setEnabled(false);
			tCardMessage.setEnabled(false);
			tSet.setEnabled(false);
			bSet.setEnabled(false);
			SetMessage.setEnabled(false);
			GetMessage.setEditable(false);
		}

		if (radioButton == e.getSource()) {
			Mode = 1;
			tSet.setEnabled(true);
		}
		if (radioButton1 == e.getSource()) {
			Mode = 2;
			tSet.setEnabled(false);
		}
		if (radioButton2 == e.getSource()) {
			Mode = 3;
			tSet.setEnabled(false);
		}
	}

	public void onCardFound(PollingEvent.CardPollingEventArg event) {

	}

	public void onCardRemoved(PollingEvent.CardPollingEventArg event) {

	}
}
